// store.ts
import { createStore, Store, useStore as baseUseStore } from "vuex";
import createPersistedState from "vuex-persistedstate";
import { InjectionKey, computed } from "vue";
import Storage from "./storage";
import getters from "./getters";
import mutations from "./mutations";
import actions from "./actions";
// module
import user from "./module/user";
import setting from "./module/setting";
import tabs from "./module/tabs";

import type { RootState } from "@model/store";

// interface/type
export const key: InjectionKey<Store<RootState>> = Symbol();

// store
const store = createStore<RootState>({
	strict: true,
	plugins: [
		// session 存储
		createPersistedState({
			storage: Storage.sessionStorage,
			reducer(state) {
				return {
					setting: {
						lang: state.setting?.lang,
						collapse: state.setting?.collapse,
						layoutSize: state.setting?.layoutSize,
					},
					user: {
						token: state.user?.token,
						permissions: state.user?.permissions,
						menuList: state.user?.menuList,
					},
					tabs: {
						activeList: state.tabs?.activeList,
						keepList: state.tabs?.keepList,
					},
				};
			},
		}),
		// local 存储
		createPersistedState({
			storage: Storage.localStorage,
			reducer(state) {
				return {
					setting: {
						openLogo: state.setting?.openLogo,
						keepHeader: state.setting?.keepHeader,
						keepTabs: state.setting?.keepTabs,
						openTabs: state.setting?.openTabs,
						uniqueOpened: state.setting?.uniqueOpened,
						openBreadcrumb: state.setting?.openBreadcrumb,
						keepAside: state.setting?.keepAside,
						isHandleAsideFixed: state.setting?.isHandleAsideFixed,
						navMode: state.setting?.navMode,
						styleMode: state.setting?.styleMode,
						routerTrans: state.setting?.routerTrans,
						asideMixinFixed: state.setting?.asideMixinFixed,
						mixinInverted: state.setting?.mixinInverted,
						menuSegmentation: state.setting?.menuSegmentation,
					},
				};
			},
		}),
	],
	state: {},
	getters,
	mutations,
	actions,
	modules: {
		user,
		setting,
		tabs,
	},
});

// define your own `useStore` composition function
export function useStore() {
	return baseUseStore(key);
}

export function useStoreComputed<T = any>(getter?: string) {
	// setting/collapse

	// setting/SET_SETTING
	const store = useStore(),
		gettersList = getter?.split("/") || [],
		moduleName = gettersList.splice(0, gettersList.length - 1).join("/"),
		getterValue = gettersList[gettersList.length - 1];
	return computed<T>({
		get: () => {
			return getter ? store.getters[getter] : store.getters;
		},
		set: (value: T) => {
			getter && store.dispatch(`${moduleName + "/"}SET_${getterValue.toUpperCase()}`, value);
		},
	});
}

export function useState(key?: string) {
	const store = useStore();
	return key ? store.state[key] : store.state;
}

export function useGetter(key?: string) {
	const store = useStore();
	return key ? store.getters[key] : store.getters;
}

export function useMutations(key: string, value?: any) {
	return useStore().commit(key, value);
}

export function useActions(key: string, value?: any) {
	return useStore().dispatch(key, value);
}

export default store;
